﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Ked
{
    class EnumFile
    {
        public EnumFile()
        {
            int logicalCoreCount = Environment.ProcessorCount;
            Debug.Print("logical core count:" + logicalCoreCount);
            if (logicalCoreCount <= 1)
                logicalCoreCount = 2;//至少两个线程
            ThreadPool.SetMaxThreads(logicalCoreCount, logicalCoreCount);
        }

        private int GetWorkingThreads()
        {
            int workingThread = 0;
            int portThread = 0;
            ThreadPool.GetAvailableThreads(out workingThread, out portThread);
            return workingThread;
        }

        private readonly AtomicInt mWorkerCounter = new AtomicInt();



        private volatile List<string> mFileList = new List<string>();
        public void DoEnumFile(string path, List<string> extList, Action<List<string>> onFileAcquired)
        {
            try
            {
                string[] files = Directory.GetFiles(path);
                List<string> fileList = new List<string>();
                foreach (string file in files)
                {
                    string ext = Path.GetExtension(file).Replace(".", "");
                    if (!extList.Contains(ext))
                        continue;
                    fileList.Add(file);
                }
                //考虑到文件夹整理的习惯，还是一次性给一个文件夹比较好
                ThreadPool.QueueUserWorkItem(new WaitCallback((x) =>
                    {
                        if (fileList.Count > 0)
                            onFileAcquired?.Invoke(fileList);
                    }));
            }
            catch (Exception) { }
            //进入子目录
            try
            {
                string[] subDirs = Directory.GetDirectories(path);

                IEnumerator dirItor = subDirs.GetEnumerator();
                while (dirItor.MoveNext())
                {
                    string currentPath = (string)dirItor.Current;
                    ThreadPool.QueueUserWorkItem(new WaitCallback((x) =>
                    {
                        DoEnumFile(currentPath, extList, onFileAcquired);

                    }));
                }
            }
            catch (Exception) { }

        }

        private readonly Dictionary<string, bool> mExitableMap = new Dictionary<string, bool>();
        private bool CheckTerminate()
        {
            bool canTerminate = true;
            lock (mExitableMap)
            {
                var itor = mExitableMap.GetEnumerator();
                while (itor.MoveNext())
                {
                    KeyValuePair<string, bool> pair = itor.Current;
                    if (!pair.Value)
                    {
                        //Thread.Sleep(2000);
                        canTerminate = false;
                    }
                }
            }
            return canTerminate;
        }
    }
}
